<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
    />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>react17 合成事件模拟</title>
  </head>
  <body>
    <div id="root">
      <div id="parent">
        <div id="child">事件执行顺序</div>
      </div>
    </div>

    <script>
      const parent = document.getElementById('parent')
      const child = document.getElementById('child')
      const root = document.getElementById('root')

      const dispatchEvent = function (event, isCapture) {
        const paths = []
        let currentTarget = event.target

        while (currentTarget) {
          paths.push(currentTarget)
          currentTarget = currentTarget.parentNode
        }

        if (isCapture) {
          // 捕获阶段
          for (let i = paths.length - 1; i >= 0; i -= 1) {
            const handler = paths[i].onClickCapture //react捕获事件
            handler && handler()
          }
        } else {
          for (let i = 0; i < paths.length; i += 1) {
            const handler = paths[i].onClick //react冒泡事件
            handler && handler()
          }
        }
      }

      root.addEventListener('click', (e) => dispatchEvent(e, true), true)
      root.addEventListener('click', (e) => dispatchEvent(e, false))

      parent.addEventListener(
        'click',
        function () {
          console.log('父元素 原生捕获事件')
        },
        true
      )
      parent.addEventListener('click', function () {
        console.log('父元素 原生冒泡事件')
      })

      child.addEventListener(
        'click',
        function () {
          console.log('子元素 原生捕获事件')
        },
        true
      )
      child.addEventListener('click', function () {
        console.log('子元素 原生冒泡事件')
      })

      document.addEventListener(
        'click',
        function () {
          console.log('document 原生捕获事件')
        },
        true
      )
      document.addEventListener('click', function () {
        console.log('document 原生冒泡事件')
      })

      parent.onClick = function () {
        console.log('父元素 React冒泡事件')
      }
      parent.onClickCapture = function () {
        console.log('父元素 React捕获事件')
      }
      child.onClick = function () {
        console.log('子元素 React冒泡事件')
      }
      child.onClickCapture = function () {
        console.log('子元素 React捕获事件')
      }
    </script>
  </body>
</html>
